﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Security.Cryptography;
using System.IO;

namespace NETCommon.Data
{
    public static class NSecurity
    {
        static string ALGORITHM_KEY = "NETCommon";
        /// <summary>
        /// Decrypt a encryption text to clear text
        /// </summary>
        /// <param name="encryptedText">Encryption text to decrypt</param>
        /// <returns>Clear text</returns>
        public static string DecryptString(string EncryptedText)
        {
            string strReturn = "";

            try
            {
                byte[] rawData = Convert.FromBase64String(EncryptedText);
                Aes aes = AesManaged.Create();

                // setup the decryption algorithm
                int nBytes = aes.BlockSize >> 3;
                byte[] salt = new byte[nBytes];
                for (int i = 0; i < salt.Length; i++)
                    salt[i] = rawData[i];

                Rfc2898DeriveBytes generateKeys = new Rfc2898DeriveBytes(ALGORITHM_KEY, salt);

                aes.Key = generateKeys.GetBytes(aes.BlockSize >> 3);
                aes.IV = salt;

                using (MemoryStream stream = new MemoryStream())
                using (ICryptoTransform decryptor = aes.CreateDecryptor())
                {
                    CryptoStream cryptoStream = new CryptoStream(stream, decryptor, CryptoStreamMode.Write);

                    cryptoStream.Write(rawData, nBytes, rawData.Length - nBytes);
                    cryptoStream.Close();

                    byte[] decryptedData = stream.ToArray();

                    strReturn = Encoding.UTF8.GetString(decryptedData);
                }
            }
            catch (Exception ex)
            {
                throw ex;
            }
            return strReturn;
        }

        /// <summary>
        /// Encrypt a clear text
        /// </summary>
        /// <param name="text">Clear text to encrypt</param>
        /// <returns>Encryption text</returns>
        public static string EncryptString(string ClearText)
        {
            string strReturn = "";

            try
            {

                byte[] rawData = Encoding.UTF8.GetBytes(ClearText);

                Aes aes = AesManaged.Create();
                int nBytes = aes.BlockSize >> 3;
                Rfc2898DeriveBytes generateKeys = new Rfc2898DeriveBytes(ALGORITHM_KEY, nBytes);
                aes.Key = generateKeys.GetBytes(nBytes);
                aes.IV = generateKeys.Salt;

                using (MemoryStream memoryStream = new MemoryStream())
                using (ICryptoTransform encryptor = aes.CreateEncryptor())
                {
                    CryptoStream cryptoStream = new CryptoStream(memoryStream, encryptor, CryptoStreamMode.Write);
                    memoryStream.Write(generateKeys.Salt, 0, generateKeys.Salt.Length);
                    cryptoStream.Write(rawData, 0, rawData.Length);
                    cryptoStream.Close();

                    byte[] encrytedData = memoryStream.ToArray();

                    strReturn = Convert.ToBase64String(encrytedData);
                }
            }
            catch (Exception ex)
            {
                throw ex;
            }
            return strReturn;
        }

    }
}
